<?php

/**
 * @name Type
 * @author Roman Metlinskyi <r.metlinskyi@gmail.com>
 */

class Type
{
  private static $_reflection = array();

  private $name;
  private $attributes;

  public function __construct($name)
  {
    $this->name = $name;
    $this->attributes = array();
  }

  private function reflection()
  {
    if (!isset(self::$_reflection[$this->name])) {
      self::$_reflection[$this->name] = new ReflectionClass($this->name);
    }
    return self::$_reflection[$this->name];
  }

  public function Attributes($name = null, $method = null)
  {
    $namespace = ($method == null) ? $this->name : "{$this->name}.$method";

    if (!isset($this->attributes[$namespace])){

      $comment = ($method == null)
              ? $this->reflection()->getDocComment()
              : $this->Methods($method)->getDocComment();

      $comment = strtr($comment, array("\r\n" => "\n", "\r" => "\n"));
      $comment = preg_replace('/^\s*\**(\s*?$|\s*)/m', '', $comment);

      $n = preg_match_all('/^@(\w+)\s+(.*)$/im', $comment, $matches);
      for ($i = 0; $i < $n; ++$i) {
        $this->attributes[$namespace][$matches[1][$i]] = $matches[2][$i];
      }
    }

    return ($name == null)
          ? $this->attributes[$namespace]
          : $this->attributes[$namespace][$name];
  }

  public function Methods($name = null)
  {
    if ($name == null)
      return $this->reflection()->getMethods();

    foreach ($this->reflection()->getMethods() as $method) {
      if (strcasecmp($method->getName(),$name)==0)
        return $method;
    }

    throw new Exception("{$name} method not found");
  }

  public function Parameters($method)
  {
    return $this->Methods($method)->getParameters();
  }
}
